package team.bailan.service.impl;

import com.auth0.jwt.JWT;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import team.bailan.common.config.ReturnResponse;
import team.bailan.common.enums.ReturnStatus;
import team.bailan.common.process.dealcard.InitialCards;
import team.bailan.common.process.ingame.InGame;
import team.bailan.common.process.ingame.InGameMap;
import team.bailan.common.process.ingame.RoomInfMap;
import team.bailan.common.process.roblord.RobLord;
import team.bailan.common.process.roblord.RobLordMap;
import team.bailan.common.util.JwtUtil;
import team.bailan.common.util.TokenUtil;
import team.bailan.entity.domain.*;
import team.bailan.entity.dto.CardsInfDTO;
import team.bailan.entity.dto.PlayerPositionDTO;
import team.bailan.entity.dto.RoomInfDTO;
import team.bailan.entity.vo.JudgeCardVO;
import team.bailan.entity.vo.PlayerPositionInfVO;
import team.bailan.mapper.UserMapper;
import team.bailan.service.GameService;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
import java.util.Map;

@Service
public class GameServiceImpl implements GameService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public ReturnResponse<JudgeCardVO> judgePlayCard(CardsInfDTO cardsInfDTO) {
        try {
            int roomId = cardsInfDTO.getRoomId();
            List<Integer> upcomingCards = cardsInfDTO.getUpcomingCards();
            InGame inGame = InGameMap.inGameMap.get("room_" + roomId);
            return ReturnResponse.OK(inGame.judgePlayCard(upcomingCards));
        } catch (Exception e) {
            return ReturnResponse.systemException(ReturnStatus.BUSINESS_EXCEPTION);
        }
    }

    @Override
    public ReturnResponse<String> playCards(CardsInfDTO cardsInfDTO) {
        try {
            int roomId = cardsInfDTO.getRoomId();
            List<Integer> upcomingCards = cardsInfDTO.getUpcomingCards();
            InGame inGame = InGameMap.inGameMap.get("room_" + roomId);
            inGame.playCards(upcomingCards);
            return ReturnResponse.OK("出牌成功");
        } catch (Exception e) {
            e.printStackTrace();
            return ReturnResponse.systemException(ReturnStatus.BUSINESS_EXCEPTION);
        }
    }

    @Override
    public ReturnResponse<String> doNotPlayCards(RoomInfDTO roomInfDTO) {
        try {
            int roomId = roomInfDTO.getRoomId();
            InGame inGame = InGameMap.inGameMap.get("room_" + roomId);
            inGame.doNotPlay();
            return ReturnResponse.OK("不出成功");
        } catch (Exception e) {
            return ReturnResponse.systemException(ReturnStatus.BUSINESS_EXCEPTION);
        }
    }

    @Override
    public ReturnResponse<Map<String, List<Card>>> getPlayerCards(RoomInfDTO roomInfDTO) {
        int roomId = roomInfDTO.getRoomId();
        InGame inGame = InGameMap.inGameMap.get("room_" + roomId);
        return ReturnResponse.OK(inGame.getPlayerCardsMap());
    }

    @Override
    public ReturnResponse<String> init(RoomInfDTO roomInfDTO) throws IOException {
        int roomId = roomInfDTO.getRoomId();
        if (InGameMap.inGameMap.containsKey("room_" + roomId)) {
            InGame.init(roomId);
            return ReturnResponse.OK("初始化成功");
        } else {
            return ReturnResponse.packageObject("未找到该房间", ReturnStatus.FAILURE);
        }

    }

    @Override
    public ReturnResponse<PlayerPositionInfVO> enterTheRoom(HttpServletRequest request, RoomInfDTO roomInfDTO) {
        try {
            int roomId = roomInfDTO.getRoomId();
            String roomLevel = RoomLevel.getRoomLevel(roomId);
            RoomInf roomInf;
            if (RoomInfMap.roomInfMap.containsKey("room_" + roomId)) {
                roomInf = RoomInfMap.roomInfMap.get("room_" + roomId);
            } else {
                roomInf = new RoomInf();
                roomInf.setRoomId(roomId);
                roomInf.setFractionCalculator(new FractionCalculator(roomLevel));
                RoomInfMap.roomInfMap.put("room_" + roomId, roomInf);
            }
            PlayerPositionInfVO playerPositionInfVO = new PlayerPositionInfVO();
            if (!roomInf.judgeFreePosition()) {
                return ReturnResponse.packageObject(null, ReturnStatus.FAILURE);
            } else {
                int userId = JwtUtil.getUserId();
                User user = userMapper.selectById(userId);
                playerPositionInfVO.setPlayerPosition(roomInf.enterTheRoom(user.getUsername(), user.getBeans()));
                playerPositionInfVO.setRoomLevel(roomLevel);
                return ReturnResponse.OK(playerPositionInfVO);
            }
        } catch (Exception e) {
            return ReturnResponse.systemException(ReturnStatus.BUSINESS_EXCEPTION);
        }
    }

    @Override
    public ReturnResponse<String> prepareForGame(PlayerPositionDTO playerPositionDTO) {
        try {
            int roomId = playerPositionDTO.getRoomId();
            int playerPosition = playerPositionDTO.getPlayerPosition();
            RoomInf roomInf;
            if (RoomInfMap.roomInfMap.containsKey("room_" + roomId)) {
                roomInf = RoomInfMap.roomInfMap.get("room_" + roomId);
            } else {
                return ReturnResponse.packageObject("出现未知错误", ReturnStatus.FAILURE);
            }
            roomInf.prepareForGame(playerPosition);
            return ReturnResponse.OK("准备成功");
        } catch (Exception e) {
            return ReturnResponse.systemException(ReturnStatus.BUSINESS_EXCEPTION);
        }
    }
}
